﻿using Shop.Core.Enums;
using Shop.Core.Repository;
using Shop.Core.Share;
using Shop.IServices;
using Shop.Model.Dto.Mine;
using Shop.Model.Entity.Order;
using Shop.Model.Entity.Use;
using Shop.Model.View.Mine;
using SqlSugar;

namespace Shop.Services;

public class MineService: IMineService
{
    private readonly RepositoryBase<Orders> _orderRepository;
    private readonly RepositoryBase<UseUser> _userRepository;
    private readonly RepositoryBase<UserWalletLog> _wallLogRepository;
    private readonly RepositoryBase<UserWallet> _walletRepository;
    private readonly RepositoryBase<OrdersGoods> _orderGoodsRepository;
    private readonly RepositoryBase<UseUserRelation> _userRelationRepository;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="orderRepository"></param>
    /// <param name="userRepository"></param>
    /// <param name="wallLogRepository"></param>
    /// <param name="walletRepository"></param>
    /// <param name="orderGoodsRepository"></param>
    /// <param name="userRelationRepository"></param>
    public MineService(RepositoryBase<Orders> orderRepository,
        RepositoryBase<UseUser> userRepository,
        RepositoryBase<UserWalletLog> wallLogRepository,
        RepositoryBase<UserWallet> walletRepository,
        RepositoryBase<OrdersGoods> orderGoodsRepository,
        RepositoryBase<UseUserRelation> userRelationRepository)
    {
        _orderRepository = orderRepository;
        _userRepository = userRepository;
        _wallLogRepository = wallLogRepository;
        _walletRepository = walletRepository;
        _orderGoodsRepository = orderGoodsRepository;
        _userRelationRepository = userRelationRepository;
    }

    /// <summary>
    /// 我的业绩
    /// </summary>
    /// <param name="uId"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public PerformanceVo Performance(long uId)
    {
        var performanceVo = new PerformanceVo();
        var userInfo = _userRepository.Where(x => x.Id == uId).First();
        if (userInfo == null)
            throw new Exception("用户信息不存在");
        var users = _userRepository
            .Where(x => x.SuperiorUser == uId)
            .OrderByDescending(x => x.Points)
            .ToList();
        if (users.Count < 2)
            performanceVo.Plot = 0;
        else
        {
            users.RemoveAt(0);
            performanceVo.Plot = users.Sum(x => x.Points);
        }
        performanceVo.Grand = userInfo.Points;
        switch (userInfo.Grade)
        {
            case 0:
                performanceVo.SumCount = 0;
                break;
            case 1:
                performanceVo.SumCount = 30;
                break;
            case 2:
                performanceVo.SumCount = 300;
                break;
            case 3:
                performanceVo.SumCount = 0;
                break;
        }
        return performanceVo;
    }

    /// <summary>
    /// 我的订单
    /// </summary>
    /// <param name="uId"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public AppResult<MyOrderVo> MyOrder(long uId)
    {
        var myOrderVo = new MyOrderVo();
        var order = _orderRepository
            .Where(x => x.UserId == uId)
            .Where(x => x.OrderStatus == (int)OrderStatus.Paid  || x.OrderStatus == (int)OrderStatus.Ship )
            .ToList();
        myOrderVo.DueIn = order.Count(x => x.OrderStatus == (int)OrderStatus.Ship);
        myOrderVo.DueOut = order.Count(x => x.OrderStatus == (int)OrderStatus.Paid);
        return myOrderVo;
    }

    /// <summary>
    /// 我的钱包
    /// </summary>
    /// <param name="uId"></param>
    /// <returns></returns>
    /// <exception cref="MyWalletVo"></exception>
    public AppResult<MyWalletVo> MyWallet(long uId)
    {
        var myWalletVo = new MyWalletVo();
        var userInfo = _walletRepository.Where(x => x.UserId == uId).First();
        if (userInfo == null)
            return new AppResult<MyWalletVo>() { Code = 400, Errors = new string[] { "用户信息不存在" } };
        myWalletVo.Balance = userInfo.Balance;
        myWalletVo.ApplyForIng = _wallLogRepository
            .Where(x => x.UserId == uId && x.State == 0 && x.Action == (int)WalletSourceTypes.Tocash)
            .Sum(x => x.Amount);
        myWalletVo.CloseAnAccount = userInfo.Surplus;
        return myWalletVo;
    }

    /// <summary>
    /// 我的收益
    /// </summary>
    /// <param name="uId"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public AppResult<MyEarningsVo> MyEarnings(long uId)
    {
        var myEarningsVo = new MyEarningsVo();
        var walletList = _wallLogRepository
            .Where(x => x.UserId == uId && x.FinishTime >= DateTime.Now.Date &&
                        x.FinishTime < DateTime.Now.AddDays(1).Date && x.State == 1)
            .Where(x => x.Action == (int)WalletSourceTypes.Distribution || x.Action == (int)WalletSourceTypes.Prize ||
                        x.Action == (int)WalletSourceTypes.Dividend)
            .ToList();
        if (walletList.Count > 0)
        {
            myEarningsVo.TodayBrokerage = walletList.Where(x => x.Action == (int)WalletSourceTypes.Distribution).Sum(x => x.Amount);
            myEarningsVo.TodaySell = walletList.Where(x => x.Action == (int)WalletSourceTypes.Prize).Sum(x => x.Amount);
            myEarningsVo.TodayTerminal = walletList.Where(x => x.Action == (int)WalletSourceTypes.Dividend).Sum(x => x.Amount);
            myEarningsVo.TodayEarnings =
                myEarningsVo.TodayBrokerage + myEarningsVo.TodaySell + myEarningsVo.TodayTerminal;
        }
        var wallet = _walletRepository.Where(x => x.UserId == uId).First();
        myEarningsVo.SumEarnings = wallet.Brokerage + wallet.Bonus + wallet.Dividend;
        myEarningsVo.SumBrokerage = wallet.Brokerage;
        myEarningsVo.SumSell = wallet.Bonus;
        myEarningsVo.SumTerminal = wallet.Dividend;
        return myEarningsVo;
    }

    /// <summary>
    /// 我的销售
    /// </summary>
    /// <param name="uId"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public AppResult<MyMarketVo> MyMarket(long uId)
    {
        var walletInfo = _wallLogRepository
            .Where(x => x.UserId == uId)
            .Where(x => x.Action == (int)WalletSourceTypes.Distribution || x.Action == (int)WalletSourceTypes.Prize)
            .OrderByDescending(x => x.CreateTime)
            .First();
        if (walletInfo != null)
        {
            var myMarketVo = _orderRepository.Queryable<Orders, UseUser>((t1, t2) => new object[]
                {
                   JoinType.Left, t1.UserId == t2.Id
                })
                .Where((t1, t2) => t1.Id == walletInfo.SourceOrder)
                .Select((t1, t2) => new MyMarketVo()
                {
                    Img = t2.Head,
                    Name = t2.Nickname,
                    OrdTime = t1.CreateTime
                })
                .First();
            var orderGoods = _orderGoodsRepository
                .Where(x => x.OrdersId == walletInfo.SourceOrder)
                .Select(x => new Goods()
                {
                    GImg = x.GoodsImage,
                    GName = x.GoodsName,
                    Count = x.GoodsQuantity
                })
                .ToList();
            myMarketVo.Goods = orderGoods;
            return myMarketVo;
        }
        else
            return  new AppResult();
    }

    /// <summary>
    /// 我的顾客
    /// </summary>
    /// <param name="uId"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public AppResult<MyCustomerVo> MyCustomer(long uId)
    {
        var myCustomerVo = new MyCustomerVo();
        var clientList = _userRelationRepository
            .Where(x => x.Ancestor == uId && x.CreateTime > DateTime.Now.AddDays(-21).Date)
            .ToList();
        myCustomerVo.SomedayClient = clientList.Count();
        myCustomerVo.TodayClient = clientList.Count(x => x.CreateTime >= DateTime.Now.Date);
        var fansList = _userRepository.Where(x => x.SuperiorUser == uId).ToList();
        myCustomerVo.SumFans = fansList.Count();
        myCustomerVo.TodayFans = fansList.Count(x => x.CreatTime >= DateTime.Now.Date);
        var clienteleList = _userRelationRepository.Queryable<UseUserRelation, UseUser>((t1, t2) => new object[]
            {
                JoinType.Left, t1.Descendant == t2.Id
            })
            .Where((t1, t2) => t1.Ancestor == uId && t2.SuperiorUser != uId)
            .ToList();
        myCustomerVo.Clientele = clienteleList.Count();
        myCustomerVo.TodayClientele = clienteleList.Count(x => x.CreateTime >= DateTime.Now.Date);
        return myCustomerVo;
    }

    /// <summary>
    /// 我的上级
    /// </summary>
    /// <param name="uId"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public AppResult<MySuperiorVo> MySuperior(long uId)
    {
        var mySuperiorVo = _userRepository.Queryable<UseUser, UseUser>((t1, t2) => new object[]
            {
                JoinType.Left, t1.SuperiorUser == t2.Id
            })
            .Where((t1, t2) => t1.Id == uId)
            .Select((t1, t2) => new MySuperiorVo()
            {
                Img = t2.Head,
                Name = t2.Nickname,
                Code = t2.Code,
                Tele = t2.Tele,
                Time = t2.CreatTime
            })
            .First();
        return mySuperiorVo;
    }

    /// <summary>
    /// 我的礼包业绩数据
    /// </summary>
    /// <param name="uId"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public AppResult<GiftBagDataVo> GiftBagData(long uId)
    {
        var giftBagDataVo = new GiftBagDataVo();
        var userInfo = _userRepository.Where(x => x.Id == uId).First();
        if (userInfo == null)
            throw new Exception("用户信息不存在");
        var users = _userRepository
            .Where(x => x.SuperiorUser == uId)
            .OrderByDescending(x => x.Points)
            .ToList();
        if (users.Count < 2)
            giftBagDataVo.Plot = 0;
        else
        {
            users.RemoveAt(0);
            giftBagDataVo.Plot = users.Sum(x => x.Points);
        }
        giftBagDataVo.Grade = userInfo.Grade;
        if (userInfo.Grade == 0)
            giftBagDataVo.GradeName = "普通";
        else if (userInfo.Grade == 1)
            giftBagDataVo.GradeName = "会员";
        else if (userInfo.Grade == 2)
            giftBagDataVo.GradeName = "至尊";
        else if (userInfo.Grade == 3)
            giftBagDataVo.GradeName = "行家";
        giftBagDataVo.Grand = userInfo.Points;
        giftBagDataVo.BuyCount = userInfo.BuyCount;
        var juniorPoint = _userRelationRepository.Queryable<UseUserRelation, Orders>((t1, t2) => new object[]
            {
                JoinType.Left, t1.Descendant == t2.UserId
            })
            .Where((t1, t2) => 
                t1.Ancestor == uId && t2.OrderStatus >= (int)OrderStatus.Paid &&
                t2.PayTime >= DateTime.Now.AddDays(-1).Date && t2.PayTime < DateTime.Now.Date)
            .Sum((t1, t2) => t2.Point);
        var myPoint = _orderRepository.Where(x =>
                x.UserId == uId && x.OrderStatus >= (int)OrderStatus.Paid &&
                x.PayTime >= DateTime.Now.AddDays(-1).Date && x.PayTime < DateTime.Now.Date)
            .Sum(x => x.Point);
        giftBagDataVo.Yesterday = juniorPoint + myPoint;
        return giftBagDataVo;
    }
}